package com.ssm.util.mybatis;


import java.util.List;

import org.apache.log4j.Logger;

import com.ssm.util.mybatis.CustomExample.Criterion;
import com.ssm.util.mybatis.ExampleType.Operation;
import com.ssm.util.mybatis.ExampleType.OrderType;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

public class ExampleUtil {

	private static Logger logger = Logger.getLogger(ExampleUtil.class);
	
	private static Example example;
	private static CustomExample customExample;

	private Criteria criteria;
	private CustomExample.Criteria customCriteria;

	private static boolean isCustom;

	private ExampleUtil(){
		customExample = new CustomExample();
		customCriteria = customExample.createCriteria();
		isCustom = true;
	}

	private ExampleUtil(Class<?> entity){
		example = new Example(entity);
		criteria = example.createCriteria();
		isCustom = false;
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 上午11:28:14
	 * @TODO 多表时使用   要用列名
	 * @return ExampleUtil
	 */
	public static ExampleUtil getInstance(){
		return new ExampleUtil();
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 上午11:28:52
	 * @TODO 单表时使用   可以用属性名代替列名
	 * @param entity 表对应的实体
	 * @return ExampleUtil
	 */
	public static ExampleUtil getInstance(Class<?> entity){
		return new ExampleUtil(entity);
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 上午11:32:02
	 * @TODO 得到example
	 * @return Object
	 */
	public Object getExample(){
		if(isCustom){
			return customExample;
		}else{
			return example;
		}
	}

	private ExampleUtil addParam(String key,Object value1,Object value2,Operation operation,List<?> values){
		if(values==null && (value1==null||value1.equals(""))){
			return this;
		}
		if(key==null || key.isEmpty()){
			logger.warn("查询条件key不能为空");
		}else{
			switch (operation) {
			case EQ:
				if(isCustom){
					customCriteria.andEqualTo(key, value1);
				}else{
					criteria.andEqualTo(key, value1);
				}
				break;
			case NOTEQ:
				if(isCustom){
					customCriteria.andNotEqualTo(key, value1);
				}else{
					criteria.andNotEqualTo(key, value1);
				}
				break;
			case BETWEEN:
				if(isCustom){
					customCriteria.andBetween(key, value1, value2);
				}else{
					criteria.andBetween(key, value1, value2);
				}
				break;
			case GT:
				if(isCustom){
					customCriteria.andGreaterThan(key, value1);
				}else{
					criteria.andGreaterThan(key, value1);
				}
				break;
			case GTE:
				if(isCustom){
					customCriteria.andGreaterThanOrEqualTo(key, value1);
				}else{
					criteria.andGreaterThanOrEqualTo(key, value1);
				}
				break;
			case LT:
				if(isCustom){
					customCriteria.andLessThan(key, value1);
				}else{
					criteria.andLessThan(key, value1);
				}
				break;
			case LTE:
				if(isCustom){
					customCriteria.andLessThanOrEqualTo(key, value1);
				}else{
					criteria.andLessThanOrEqualTo(key, value1);
				}
				break;
			case LIKE:
				if(isCustom){
					customCriteria.andCondition(key+ " like '%" +value1 +"%'");
				}else{
					criteria.andCondition(key+ " like '%" +value1 +"%'");
				}
				break;
			case IN:
				if(isCustom){
					customCriteria.andIn(key, values);
				}else{
					criteria.andIn(key, values);
				}
				break;
			case NOTIN:
				if(isCustom){
					customCriteria.andNotIn(key, values);
				}else{
					criteria.andNotIn(key, values);
				}
				break;
			case ISNULL:
				if(isCustom){
					customCriteria.andIsNull(key);
				}else{
					criteria.andIsNull(key);
				}
				break;
			case ISNOTNULL:
				if(isCustom){
					customCriteria.andIsNotNull(key);
				}else{
					criteria.andIsNotNull(key);
				}
				break;
			default:
				break;
			}
		}
		return this;
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 上午11:53:57
	 * @TODO 添加条件   手写
	 * @param condition
	 * @return ExampleUtil
	 */
	public ExampleUtil addParam(String condition){
		if(isCustom){
			customCriteria.andCondition(condition);
		}else{
			criteria.andCondition(condition);
		}
		return this;
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 上午11:51:06
	 * @TODO 添加条件
	 * @param key
	 * @param value
	 * @param operation
	 * @return ExampleUtil
	 */
	public ExampleUtil addParam(String key,Object value,Operation operation){
		addParam(key,value,null,operation,null);
		return this;
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 上午11:50:36
	 * @TODO 添加条件   默认是等于
	 * @param key
	 * @param value
	 * @return ExampleUtil
	 */
	public ExampleUtil addParam(String key,Object value){
		addParam(key,value,null,Operation.EQ,null);
		return this;
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 上午11:53:26
	 * @TODO 添加条件  要在两个值中间
	 * @param key
	 * @param value1
	 * @param value2
	 * @return ExampleUtil
	 */
	public ExampleUtil addParam(String key,Object value1,Object value2){
		addParam(key, value1, value2, Operation.BETWEEN,null);
		return this;
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 下午12:15:11
	 * @TODO 添加条件  in或者notin
	 * @param key
	 * @param values
	 * @return ExampleUtil
	 */
	public ExampleUtil addParam(String key,List<?> values,Operation operation){
		addParam(key, null, null, operation,values);
		return this;
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 下午12:20:25
	 * @TODO 添加条件   isnull  或者 isnotnull
	 * @param key
	 * @param operation
	 * @return ExampleUtil
	 */
	public ExampleUtil addParam(String key,Operation operation){
		addParam(key, null, null, operation,null);
		return this;
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 下午12:21:30
	 * @TODO 添加排序
	 * @param order
	 * @return ExampleUtil
	 */
	public ExampleUtil addOrder(String order,OrderType orderType){
		if(isCustom){
			String orderTemp = customExample.getOrderByClause();
			orderTemp  = orderTemp==null?"":orderTemp+" ,";
			customExample.setOrderByClause(orderTemp+" "+order+" "+orderType.toString());
		}else{
			String orderTemp = example.getOrderByClause();
			orderTemp  = orderTemp==null?"":orderTemp+" ,";
			example.setOrderByClause(orderTemp+" "+order+" "+orderType.toString());
		}
		return this;
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 下午12:24:36
	 * @TODO TODO
	 * @param order
	 * @return ExampleUtil
	 */
	public ExampleUtil addOrder(String order){
		if(isCustom){
			customExample.setOrderByClause(order+" ASC");
		}else{
			example.setOrderByClause(order+" ASC");
		}
		return this;
	}
	
	public ExampleUtil addGroup(String group){
		if(isCustom){
			customExample.setGroupByClause(group);
		}
		return this;
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 下午12:59:16
	 * @TODO 添加or语句
	 * @param example
	 * @return ExampleUtil
	 */
	public ExampleUtil addOr(Example example){
		for(Criteria criteria: example.getOredCriteria()){
			ExampleUtil.example.or(criteria);
		}
		return this;
	}

	/**
	 * 
	 * @Author 执笔
	 * @Date 2016年1月6日 下午12:59:16
	 * @TODO 添加or语句
	 * @param example
	 * @return ExampleUtil
	 */
	public ExampleUtil addOr(CustomExample example){
		for(CustomExample.Criteria criteria: example.getOredCriteria()){
			ExampleUtil.customExample.or(criteria);
		}
		return this;
	}

	public static void main(String[] args) {

		CustomExample customExample2 = (CustomExample) ExampleUtil.getInstance().addParam("123ss")
				.addOrder("456888").addParam("456","123").getExample();
		CustomExample customExample = (CustomExample) ExampleUtil.getInstance().addParam("123").addParam("456","123")
				.addOr(customExample2).getExample();
		for(CustomExample.Criteria criteria : customExample.getOredCriteria()){
			for(Criterion criterion : criteria.getAllCriteria()){
				System.out.println(criterion.getCondition()+criterion.getTypeHandler()+criterion.getValue());
			}
		}
	}
}
